from django import forms
from django.shortcuts import HttpResponse, render, redirect
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError

from app01 import models

"""
    靓号管理
"""


def pretty_list(request):
    """靓号列表"""
    search_dict = {}
    search_value = request.GET.get('search', '').strip()
    if search_value:
        search_dict['mobile__contains'] = search_value

    # 获取并验证分页参数
    try:
        page = max(1, int(request.GET.get('page', 1)))
    except ValueError:
        page = 1

    try:
        limit = max(1, min(100, int(request.GET.get('limit', 10))))
    except ValueError:
        limit = 10

    # 查询数据并排序
    queryset = models.PrettyNum.objects.filter(**search_dict).order_by('-level')

    # 使用Django的Paginator进行分页
    paginator = Paginator(queryset, limit)
    try:
        data_list = paginator.page(page)
    except PageNotAnInteger:
        data_list = paginator.page(1)
    except EmptyPage:
        data_list = paginator.page(paginator.num_pages)

    context = {
        'data_list': data_list,
        'search_value': search_value,
        'totals': paginator.count,
        'current_page': data_list.number,
        'page_size': limit,
        'total_pages': paginator.num_pages,
    }
    return render(request, 'pretty/list.html', context)


class PrettyModelForm(forms.ModelForm):
    """定义一个类去继承forms.ModelForm"""
    """验证数据方式1"""
    mobile = forms.CharField(
        label='靓号号码',
        min_length=11,
        max_length=11,
        validators=[
            RegexValidator(
                regex=r'^1[3-9]\d{9}$',
                message='手机号格式错误'
            ),
        ]
    )

    class Meta:
        model = models.PrettyNum
        # fields = ['mobile', 'price', 'level', 'status']  # 自定义字段名
        fields = "__all__"  # 取全部字段
        # exclude = ["status"] # 排除某个字段

    # 执行init时,重新定义父类的init方法
    def __init__(self, *args, **kwargs):
        super(PrettyModelForm, self).__init__(*args, **kwargs)  # 正确地调用父类的构造函数
        for name, field in self.fields.items():
            field.widget.attrs = {"class": "layui-input", "placeholder": field.label, "lay-affix": "clear"}

    """
        验证数据方式2
        我这里字段有mobile,price,level,status,就可以写钩子方法 def clean_字段名
        我这里可以组合使用,例如我先校验手机号是否可以通过正则校验,我在校验是否已存在库中
    """

    def clean_mobile(self):
        """构子方法"""
        txt_mobile = self.cleaned_data['mobile']
        # 检查手机号是否满足11位
        if len(txt_mobile) != 11:
            raise ValidationError('手机号码格式错误')
        # 检查数据库中是否存在相同的手机号
        if models.PrettyNum.objects.filter(mobile=txt_mobile).exists():
            raise ValidationError('此手机号已存在')
        # 校验通过
        return txt_mobile


def pretty_add(request):
    """新建靓号"使用ModelForm组件"""
    if request.method == 'GET':
        form = PrettyModelForm()
        return render(request, 'pretty/model_form_add.html', {"form": form})
    # 用户post提交数据，开始数据校验
    form = PrettyModelForm(data=request.POST)
    if form.is_valid():
        # print(form.cleaned_data)
        # 如果数据校验通过，就会在这里执行
        form.save()  # 数据保存
        return redirect('/pretty/list/')
    else:
        # 数据校验失败，就会在这里执行
        print(form.errors)
        return render(request, 'pretty/model_form_add.html', {"form": form})


class PrettyModelFormEdit(forms.ModelForm):
    """定义一个类去继承forms.ModelForm，我这里编辑，只让他修改等级之类，手机号码不能修改 """
    mobile = forms.CharField(label='手机号', disabled=True)

    class Meta:
        model = models.PrettyNum
        fields = ['mobile', 'price', 'level', 'status']  # 自定义字段名
        # exclude = ["'mobile'"] # 排除某个字段

    # 执行init时,重新定义父类的init方法
    def __init__(self, *args, **kwargs):
        super(PrettyModelFormEdit, self).__init__(*args, **kwargs)  # 正确地调用父类的构造函数
        for name, field in self.fields.items():
            field.widget.attrs = {"class": "layui-input", "placeholder": field.label, "lay-affix": "clear"}

    """
        验证数据方式2
        我这里字段有mobile就可以写钩子方法 def clean_字段名
        编辑业务状态下，如果我没有修改手机号，但是我有需求设置了手机号不允许重复怎么办？
    """

    def clean_mobile(self):
        """构子方法
            self.instance.pk 就是当前编辑数据的id
        """
        print(self.instance.pk)
        txt_mobile = self.cleaned_data['mobile']
        if models.PrettyNum.objects.exclude(id=self.instance.pk).filter(mobile=txt_mobile).exists():
            # 排除我自己的数据，我去库里找一圈是否还存在手机号相同的情况，如果没有就表示手机号是可以被插入的
            raise ValidationError('此手机号已存在')
        # 校验通过
        return txt_mobile


def pretty_edit(request, pretty_id):
    """编辑靓号使用ModelForm组件"""
    row_obj = models.PrettyNum.objects.filter(id=pretty_id).first()  # 查询对应数据

    if request.method == 'GET':
        form = PrettyModelFormEdit(instance=row_obj)  # 让实例等于查询的结果，双向绑定
        return render(request, 'pretty/model_form_edit.html', {"form": form})

    # 开始数据校验
    form = PrettyModelFormEdit(data=request.POST, instance=row_obj)  # 这样写就是，我拿到对应id的数据，然后使用MoelForm来更新
    if form.is_valid():
        # print(form.cleaned_data)
        # 默认保存的是用户输入的所有数据，如果表里有个特殊字段，我们要写入数据可以 这样
        # form.instance.字段名 = 字段值
        # 如果数据校验通过，就会在这里执行
        form.save()  # 数据保存
        return redirect('/pretty/list/')
    else:
        # 数据校验失败，就会在这里执行
        print(form.errors)
        return render(request, 'pretty/model_form_edit.html', {"form": form})


def pretty_delete(request):
    """删除靓号记录"""
    pretty_id = request.GET.get('pretty_id')
    models.PrettyNum.objects.filter(id=pretty_id).delete()
    return redirect('/pretty/list/')
